<template>
  <div class="container" :style="pageStyle">
    <!-- 这是操作提示 -->
    <div class="guideMask" @click="hideGuideMask" v-if="showGuide">
      <div
        class="guideMaskImg"
        :style="'background:url('+guideImg+') center center / contain no-repeat;'"
      ></div>
    </div>
    <!-- <div class="mask" @click="doClick"></div> -->
    <!-- 这是加载中遮罩，防止用户看到页面跳动 -->
    <transition name="fade">
      <div v-show="showLoadingMask" class="loading_mask"></div>
    </transition>
    <div id="area" @click="doClick"></div>
    <tool-bar
      :isShow="showToolBar"
      :progress="progress"
      :fontSize="fontSize"
      :selectedColor="themeName"
      @onChangeFontsize="onChangeFontsize"
      @onThemeSelect="onThemeSelect"
      @openCatalog="openCatalog"
      ref="toolBar"
    />
    <catagory
      :showCatagory="showCatagory"
      :toc="toc"
      @gotoPage="gotoPage"
      :bookId="bookId || ''"
      @gotoCfi="gotoCfi"
      :bookMarks="bookMarks"
    />
    <cc-dialog
      :isShow="BuyDialog"
      @onCancel="cancelDialog"
      @onConfirm="goBuy"
      message="該內容需要購買才可繼續閱讀"
      confirmText="立即購買"
    />
  </div>
</template>

<script>
import ToolBar from "../components/ReaderToolBar";
import Catagory from "../components/catagory.vue";
import CcDialog from "../components/dialog.vue";

import axios from "axios";

import ePub from "../epub/epub.js";
import jszip from "../epub/jszip.min.js";

var CryptoJS = require("crypto-js");

import { defer, isXml, parse } from "../epub/utils/core";
import Path from "../epub/utils/path";
import { setTimeout } from "timers";
import { log } from "util";

import { SERVER } from "@/api/apiConfig.js";

export default {
  data() {
    return {
      isNative: false,
      isLogin: false,
      bookId: null,
      bookData: null,
      progress: 0,
      book: null,
      rendition: null,
      showCatagory: 0,
      toc: null,
      clientWidth: 0,
      loading: false,
      showToolBar: null,
      show: null,
      windowWidth: 500,
      windowHeight: 500,
      toolbarIsShow: false,
      BuyDialog: false,
      fontSize: 1,
      themeName: 0,
      backgroundColor: null,
      needBuy: false,
      showGuide: false,
      limitSection: null,
      guideImg: require("@/assets/image/icon/guide.png"),
      checkPage: true, //是否需要校正
      showLoadingMask: true,
      historyPage: 1,
      tryTime: 1,
      localPathname: null,
      token: null, //請求接口的token
      clickText: null,
      progressObj: {},
      bookMarks: [],
      thisPageIsMark: null
    };
  },
  watch: {},
  computed: {
    pageStyle() {
      if (this.backgroundColor) {
        return {
          "background-color": this.backgroundColor
        };
      } else {
        return {
          "background-color": this.$config.themes[this.themeName].color
        };
      }
    }
  },

  components: {
    ToolBar,
    Catagory,
    CcDialog
  },
  mounted() {
    window["dataTransmission"] = this.dataTransmission;
    window["bookmarksItemCallback"] = this.addBookMark;

    try {
      native.webViewOnload();
      this.isNative = true;
      native.hideNavigation();
      native.interactivePopDisabled(true); // 禁止ios左滑返回操作（Android沒有這個方法）
      native.disabledBounce(); //禁止上下滾動（Android沒有這個方法）
    } catch (error) {}

    let localPath = window.location.origin + window.location.pathname;
    let paths = localPath.split("/");
    let newPath = "";
    paths.forEach((str, index) => {
      if (index < paths.length - 1) {
        newPath += str + "/";
      }
    });
    this.localPathname = newPath;

    this.windowWidth = document.body.clientWidth;
    this.windowHeight = document.body.clientHeight * 0.97; //document.body.clientHeight; 預留topbar位置
    this.clientWidth = document.body.clientWidth;
    this.bookId =
      this.$route.query.src ||
      // decodeURIComponent(
      //   "http%3A%2F%2Fnowbook-info.oss-cn-hongkong.aliyuncs.com%2FLzE1NDYyMzUzNTgwOTMwMDNfMW0uZXB1Yg%3FExpires%3D1546238956%26OSSAccessKeyId%3DLTAI3MlVyHfQ7xyf%26Signature%3DyWguN9IDBTZMH%252FvZNk09GWIIKJ0%253D"
      // );
      //"05b4cbe0473d407fbfe4d6d962316d23";
      "0b9afcc706a545829b816e30abbf55fa";

    //"d278cfa209c64c45a5a89f99f295ec30"; //香港历史散步

    //讀取客戶端緩存，判斷是否首次，顯示指引
    if (this.isNative) {
      var dataValue = native.getStorage("reader_showGuide");
      try {
        let settingObj = JSON.parse(dataValue);
        this.showGuide = false;
      } catch (error) {
        this.showGuide = true;
      }
    }

    //判断用户是否登录
    this.LOGIN.get(false).then(res => {
      if (res.session != null) {
        this.isLogin = true;
        //判断是否游客
        if (res.userType && res.userType != "normal") {
          //如果是游客则认为没有登录
          this.isLogin = false;
        }

        if (this.isNative && this.isLogin) {
          native.showBookmarksIcon(false); //顯示書籤接口
        }
      } else {
        this.isLogin = false;
      }
    });

    //this.getBook(); //调试

    if (!this.isNative) {
      this.getBook();
    }
  },
  methods: {
    hideGuideMask() {
      this.showGuide = false;
      let settingObj = {
        showGuide: 1
      };
      //保存設置到本地
      if (this.isNative) {
        var setData = {
          key: "reader_showGuide",
          value: JSON.stringify(settingObj)
        };
        native.setStorage(JSON.stringify(setData));
      }
    },
    dataTransmission(params) {
      try {
        let obj = JSON.parse(params);
        this.bookId = obj.id; //ID
        this.historyCfi = obj.cfi || null; //進度
        this.limitSection = obj.limitSection || 2; //顯示張姐
        if (this.book) {
          this.book.destroy(); // 銷毀當前書籍，重新渲染
          this.rendition.clear();
          document.getElementById("area").innerHTML = ""; //清空HTML内容
        }
        if (this.bookId) {
          this.getBook();
        }
      } catch (error) {}
    },

    addBookMark() {
      this.$refs.toolBar.doHide(); //隱藏

      if (this.thisPageIsMark != null) {
        //删除书签
        this.cancelBookmark(this.thisPageIsMark);
      } else {
        //添加书签
        //兼容沒有clickText的情況
        if (!(this.clickText && this.clickText.length > 0)) {
          this.clickText = `第${this.progressObj.chapter}章第${
            this.progressObj.page
          }頁`;
        }

        //裁剪20個字
        if (this.clickText.length > 20) {
          this.clickText = this.clickText.substring(0, 20);
        }
        //添加書籤
        let postD = {
          cfi: this.progressObj.cfi,
          posY: this.progressObj.page,
          name: this.clickText,
          mediaId: this.bookId
        };

        let url = this.CONFIG.epub.addBookMark;

        this.GLOBAL_.ccRequest
          .doSessionAxios(url, postD, "POST", "no login")
          .then(res => {
            if (this.isNative) {
              native.showToast("添加書籤成功");
              native.showBookmarksIcon(true);
            }
            this.thisPageIsMark = res.id;
            //刷新书签数据
            this.loadBookMark();
          })
          .catch(err => {
            // console.log("err", JSON.stringify(err));
          });
      }
    },

    //加载书签
    loadBookMark() {
      let postD = {
        pageNo: 1,
        pageSize: 99999,
        mediaId: this.bookId
      };
      let url = this.CONFIG.epub.getBookMark;
      this.GLOBAL_.ccRequest
        .doSessionAxios(url, postD, "POST", "no login")
        .then(res => {
          this.bookMarks = res.rows;
        })
        .catch(err => {
          // console.log("err", JSON.stringify(err));
        });
    },

    cancelBookmark(id) {
      let postD = {
        ids: id
      };
      let url = this.CONFIG.epub.deleteBookMark;
      this.GLOBAL_.ccRequest
        .doSessionAxios(url, postD, "POST", "no login")
        .then(res => {
          if (this.isNative) {
            native.showToast("取消書籤成功");
            native.showBookmarksIcon(false);
            this.thisPageIsMark = null;
          }
          this.loadBookMark();
        })
        .catch(err => {
          // console.log("err", JSON.stringify(err));
        });
    },

    checkBookmark(cfi, page) {
      let id = null;
      //检查当前页是否打过标签
      this.bookMarks.forEach(mark => {
        if (mark.cfi == cfi && mark.posY == page) {
          id = mark.id;
        }
      });
      return id;
    },

    goBuy() {
      //判断用户登录状态
      if (!this.isLogin) {
        //未登录
        //判断是否匿名登录
        this.LOGIN.get(false).then(res => {
          if (res.session == null) {
            //android 没有登录
            this.doLogin();
            return;
          }

          this.BuyDialog = false;
          let obj = {
            router: this.$router,
            path: "index.html#/app/buy",
            query: {
              objType: "media",
              id: this.bookId
            }
          };
          //监听窗口关闭窗口返回事件
          window["prevWindowsParams"] = this.buyCallback;
          window["closeWindowsCallback"] = this.buyCallback;
          this.GLOBAL_.ccApp.openTo(obj);
        });
      } else {
        this.BuyDialog = false;
        let obj = {
          router: this.$router,
          path: "index.html#/app/buy",
          query: {
            objType: "media",
            id: this.bookId
          }
        };
        //监听窗口关闭窗口返回事件
        window["prevWindowsParams"] = this.buyCallback;
        window["closeWindowsCallback"] = this.buyCallback;
        this.GLOBAL_.ccApp.openTo(obj);
      }
    },

    //購買回調
    buyCallback() {
      this.getBook();
    },

    cancelDialog() {
      this.BuyDialog = false;
    },

    //獲取電子書信息
    getBook() {
      if (this.book) {
        this.book.destroy(); // 銷毀當前書籍，重新渲染
        this.rendition.clear();
        document.getElementById("area").innerHTML = ""; //清空HTML内容
      }

      this.needBuy = true;
      if (this.isNative) {
        native.showLoadingText("加載中...");
      }

      this.getToken(this.bookId)
        .then(res => {
          this.token = res;
          if (res.isBuy != 1 && res.salePrice > 0 && res.canTry > 0) {
            //设置试读限制
            this.limitSection = res.probation;
          } else {
            this.limitSection = null;
          }

          //设置购买状态
          if (res.isBuy == 1) {
            this.needBuy = false;
          }

          if (res.ebookProgress) {
            //歷史記錄
            this.historyCfi = res.ebookProgress.cfi;
            this.historyPage = res.ebookProgress.page || 1;
          }
          this.loadBookMark(); // 加载书签
          this.loadBook(this.bookId);
        })
        .catch(err => {
          if (this.isNative) {
            native.showToast("請求授權失敗");
            native.hideLoading();
          }
        });
    },

    //打开登录界面
    doLogin() {
      let obj = {
        router: this.$router,
        path: "index.html#/app/login",
        query: {}
      };
      //监听窗口关闭窗口返回事件
      window["closeWindowsCallback"] = this.loginCallback;
      window["prevWindowsParams"] = this.loginCallback;
      this.BuyDialog = false; // 隐藏购买弹窗
      this.GLOBAL_.ccApp.openTo(obj);
    },

    updataBookInfo() {
      if (this.isNative) {
        native.showLoadingText("加載中...");
      }

      this.needBuy = false;
      let postD = {
        id: this.bookId
      };
      this.GLOBAL_.ccRequest
        .doSessionAxios(this.CONFIG.MEDIA.GET, postD, "GET", "no login")
        .then(res => {
          if (res.isBuy == 1) {
            this.needBuy = false;
            this.BuyDialog = false; //显示购买弹窗
            this.checkToc();
          } else {
            this.BuyDialog = true; //显示购买弹窗
          }
          native.hideLoading();
        })
        .catch(err => {
          //獲取多媒體數據異常
          if (this.isNative) {
            native.showToast("加载数据失败");
            native.hideLoading();
          }
        });
    },

    //登录回调
    loginCallback() {
      //alert("login callback:");
      // console.log("loginCallback is OK");

      //判断用户是否登录
      this.LOGIN.get(false).then(res => {
        if (res.session != null) {
          this.isLogin = true;
        } else {
          this.isLogin = false;
        }
      });

      //检查当前页是否有添加书签
      let markId = this.checkBookmark(
        this.progressObj.cfi,
        this.progressObj.page
      );

      if (markId != null) {
        this.thisPageIsMark = markId;
        if (this.isNative && this.isLogin) {
          native.showBookmarksIcon(true);
        }
      } else {
        this.thisPageIsMark = null;
        if (this.isNative && this.isLogin) {
          native.showBookmarksIcon(false);
        }
      }

      //更新用戶購買狀態
      this.updataBookInfo();
    },

    //获取阿里云token
    getToken(id) {
      let that = this;
      return new Promise(function(resolve, reject) {
        let url = that.CONFIG.epub.token;
        let postD = {
          id: id,
          expireSecond: 60 * 7 //調試token過期
        };
        that.GLOBAL_.ccRequest
          .doSessionAxios(url, postD, "GET", "no login")
          .then(res => {
            resolve(res);
          })
          .catch(err => {
            reject();
          });
      });
    },

    //对URL进行加密
    signatureUrl(path, opt) {
      //判斷token是否過期
      let time = new Date().getTime();
      let that = this;
      return new Promise(function(resolve, reject) {
        //接近5分鐘時，重新獲取授權
        if (time > that.token.expireTime - 5 * 60 * 1000) {
          //過期
          that
            .getToken(that.bookId)
            .then(res => {
              that.token = res;
              let url = `${SERVER.URL}api/media/epub/read/${
                that.bookId
              }${path}?token=${that.token.token}`;
              resolve(url);
            })
            .catch(err => {
              if (that.isNative) {
                native.showToast("請求授權失敗");
              }
              reject();
            });
        } else {
          //未過期
          let url = `${SERVER.URL}api/media/epub/read/${
            that.bookId
          }${path}?token=${that.token.token}`;
          resolve(url);
        }
      });
    },

    //获取图片URL
    getImageUrl(imgPath) {
      let imgUrl = `${SERVER.URL}api/media/epub/read/${
        this.bookId
      }${imgPath}?process=image/resize,w_${parseInt(
        this.windowWidth * this.DPR
      )}&token=${this.token.token}`;
      return imgUrl;
    },

    getChapterNum(url) {
      let chapterNum = 0;
      //正则匹配
      let reg = /chapter(\d+)\.xhtml/gi;
      let result = null;
      if ((result = reg.exec(url)) != null) {
        chapterNum = result[1] * 1;
      }

      //匹配是否最后的postscript
      let reg2 = /postscript(\d+)\.xhtml/gi;
      let result2 = null;
      if ((result2 = reg2.exec(url)) != null) {
        chapterNum = 9999;
      }

      //匹配是否最后的postscript
      let reg3 = /bibliography(\d+)\.xhtml/gi;
      let result3 = null;
      if ((result3 = reg3.exec(url)) != null) {
        chapterNum = 9999;
      }

      return chapterNum;
    },

    canShowBugDialog(href, forceShowBugDialog) {
      let cn = this.getChapterNum(href);
      let xxx = cn - this.progressObj.chapter;

      //判断href 更当前显示的是否一致，如果不一致，则不弹出
      if (forceShowBugDialog != undefined && forceShowBugDialog) {
        this.BuyDialog = true;
      } else if (xxx == 1 || xxx > 9000) {
        //如果章节数大于1，才显示弹窗
        this.BuyDialog = true;
      }
    },

    checkChapterCanRead(url, forceShowBugDialog) {
      //console.log("检查章节是否可阅读章节=>", url);
      //console.log("this.toc=>", JSON.stringify(this.toc));

      if (this.limitSection == null) {
        return true;
      }

      if (this.toc != null) {
        let ct = false;
        for (let index = 0; index < this.toc.length; index++) {
          if (url.indexOf(this.toc[index].href) >= 0) {
            if (!this.toc[index].canTry) {
              //this.BuyDialog = true;
              this.canShowBugDialog(url, forceShowBugDialog);
              this.needBuy = true;
            }
            return this.toc[index].canTry;
          }

          if (this.toc[index].subitems && this.toc[index].subitems.length > 0) {
            for (let idx = 0; idx < this.toc[index].subitems.length; idx++) {
              if (url.indexOf(this.toc[index].subitems[idx].href) >= 0) {
                if (!this.toc[index].subitems[idx].canTry) {
                  //this.BuyDialog = true;
                  this.canShowBugDialog(url, forceShowBugDialog);
                  this.needBuy = true;
                }
                return this.toc[index].subitems[idx].canTry;
              }
            }
          }
        }

        //兼容分部分的情况

        let chapNum = this.getChapterNum(url);
        if (chapNum > this.limitSection) {
          //this.BuyDialog = true;
          this.canShowBugDialog(url);
          this.needBuy = true;
          return false;
        } else {
          return true;
        }
      } else {
        return true;
      }
    },

    getPathFromUrl(url) {
      let href = window.location.href;
      let path = url.substring(this.localPathname.length - 1, url.length);
      return path;
    },

    //重写epub的request方法

    async myEpubRequest(url, type, withCredentials, headers) {
      //判斷是否超過試閱限制

      // if (!this.checkChapterCanRead(url)) {
      //   console.log("調試信息！！！000");
      //   var deferred = new defer();
      //   return deferred.promise;
      // }

      //替换加密URL
      // let href = window.location.href;
      // //window.location.href.split("/reader.html")[0];
      // let path = url.substring(
      //   window.location.href.split("/reader.html")[0].length,
      //   url.length
      // );

      let path = this.getPathFromUrl(url);
      var deferred = new defer();

      // console.log("请求的path", path);

      if (!this.checkChapterCanRead(path)) {
        //超出试读限制
        deferred.reject({
          status: this.status,
          response: this.response,
          message: "Forbidden",
          stack: new Error().stack
        });
        return deferred.promise;
      }

      let sUrl = await this.signatureUrl(path);
      url = sUrl;

      let that = this;

      var supportsURL = typeof window != "undefined" ? window.URL : false; // TODO: fallback for url if window isn't defined
      var BLOB_RESPONSE = supportsURL ? "blob" : "arraybuffer";

      var xhr = new XMLHttpRequest();

      var xhrPrototype = XMLHttpRequest.prototype;

      var header;

      if (!("overrideMimeType" in xhrPrototype)) {
        // IE10 might have response, but not overrideMimeType
        Object.defineProperty(xhrPrototype, "overrideMimeType", {
          value: function xmlHttpRequestOverrideMimeType() {}
        });
      }

      if (withCredentials) {
        xhr.withCredentials = true;
      }

      function err(e) {
        deferred.reject(e);
      }

      function handler() {
        if (this.readyState === XMLHttpRequest.DONE) {
          var responseXML = false;

          if (this.responseType === "" || this.responseType === "document") {
            responseXML = this.responseXML;
          }

          //訪問權限異常處理
          if (
            this.status === 403 ||
            this.status === 400 ||
            this.status === 402
          ) {
            if (this.status === 403) {
              //超出試閱範圍
              // console.log("服務端返回403");
              that.BuyDialog = true;
              //弹出购买提示

              deferred.reject({
                status: this.status,
                response: this.response,
                message: "Forbidden",
                stack: new Error().stack
              });
              return deferred.promise;
            }

            if (this.status === 402) {
              //token過期
              //重新請求token
              deferred.reject({
                status: this.status,
                response: this.response,
                message: "Forbidden",
                stack: new Error().stack
              });
              return deferred.promise;
            }

            deferred.reject({
              status: this.status,
              response: this.response,
              message: "Forbidden",
              stack: new Error().stack
            });
            return deferred.promise;
          }

          if (this.status === 200 || this.status === 0 || responseXML) {
            //-- Firefox is reporting 0 for blob urls
            var r;

            if (!this.response && !responseXML) {
              deferred.reject({
                status: this.status,
                message: "Empty Response",
                stack: new Error().stack
              });
              return deferred.promise;
            }

            if (this.status === 403) {
              deferred.reject({
                status: this.status,
                response: this.response,
                message: "Forbidden",
                stack: new Error().stack
              });
              return deferred.promise;
            }
            if (responseXML) {
              r = this.responseXML;
            } else if (isXml(type)) {
              // xhr.overrideMimeType("text/xml"); // for OPF parsing
              // If this.responseXML wasn't set, try to parse using a DOMParser from text

              r = parse(this.response, "text/xml");
            } else if (type == "xhtml") {
              /**
               *
               */

              //要在这里解密
              // var decryptedRes = that.decryptStr(
              //   this.response,
              //   "ZGIyMTM5NTYxYzlmZTA2OA=="
              // );

              /**
               *
               */

              //替换DIV
              r = parse(this.response, "application/xhtml+xml");
            } else if (type == "html" || type == "htm") {
              r = parse(this.response, "text/html");
            } else if (type == "json") {
              r = JSON.parse(this.response);
            } else if (type == "blob") {
              if (supportsURL) {
                r = this.response;
              } else {
                //-- Safari doesn't support responseType blob, so create a blob from arraybuffer
                r = new Blob([this.response]);
              }
            } else {
              r = this.response;
            }
            deferred.resolve(r);
          } else {
            deferred.reject({
              status: this.status,
              message: this.response,
              stack: new Error().stack
            });
          }
        }
      }

      xhr.onreadystatechange = handler;
      xhr.onerror = err;

      xhr.open("GET", url, true);

      for (header in headers) {
        xhr.setRequestHeader(header, headers[header]);
      }

      if (type == "json") {
        xhr.setRequestHeader("Accept", "application/json");
      }

      // If type isn"t set, determine it from the file extension
      if (!type) {
        type = new Path(url).extension;
      }

      if (type == "blob") {
        xhr.responseType = BLOB_RESPONSE;
      }

      if (isXml(type)) {
        // xhr.responseType = "document";
        xhr.overrideMimeType("text/xml"); // for OPF parsing
      }

      if (type == "xhtml") {
        // xhr.responseType = "document";
        //调试
        //xhr.responseType = "arraybuffer";
      }

      if (type == "html" || type == "htm") {
        // xhr.responseType = "document";
      }

      if (type == "binary") {
        xhr.responseType = "arraybuffer";
      }

      xhr.send();
      return deferred.promise;
    },

    checkToc() {
      //设置试读限制
      let finded = false;

      //遍歷目錄
      this.toc.forEach(item => {
        if (item.subitems && item.subitems.length > 0) {
          //如果有subitems => 遍歷subitems
          let partHasCanTry = false;

          item.subitems.forEach(subitem => {
            //已经找到试读章节 且未购买
            if (finded && this.needBuy) {
              subitem.canTry = false;
              return;
            }

            if (!this.needBuy) {
              //已购买，不限制
              subitem.canTry = true;
              item.canTry = true;
              return;
            }

            let chapterNum = this.getChapterNum(subitem.href);
            if (chapterNum > 0 && chapterNum > this.limitSection) {
              if (chapterNum > this.limitSection) {
                subitem.canTry = false;
                finded = true;
              }
            } else {
              subitem.canTry = true;
              partHasCanTry = true;
            }
          });

          if (partHasCanTry && this.needBuy) {
            item.canTry = true;
          } else if (this.needBuy) {
            item.canTry = false;
          }
        } else {
          if (finded && this.needBuy) {
            item.canTry = false;
            return;
          }

          if (!this.needBuy) {
            //已购买，不限制
            item.canTry = true;
            return;
          }

          let cn = this.getChapterNum(item.href);

          if (cn > 0 && cn < 9000 && cn > this.limitSection) {
            item.canTry = false;
            finded = true;
          } else if (cn > 9000 && !finded) {
            //附录等，前面未找到限制章节，则附录也可以试读
            item.canTry = true;
          } else {
            item.canTry = true;
          }
          let obj = {
            label: item.label,
            href: item.href,
            id: item.id,
            canTry: item.canTry
          };
        }
      });
    },

    //对服务端返回密文进行解密
    decryptStr(encryptStr, keyStr) {
      //要再这里解密
      var key = CryptoJS.enc.Base64.parse(keyStr);
      var iv = CryptoJS.enc.Base64.parse(keyStr);
      // 拿到字符串类型的密文需要先将其用Hex方法parse一下
      var cipherTextHexStr = CryptoJS.enc.Hex.parse(encryptStr);
      var decrypted = CryptoJS.AES.decrypt(
        { ciphertext: cipherTextHexStr },
        key,
        {
          iv: iv,
          padding: CryptoJS.pad.Pkcs7,
          mode: CryptoJS.mode.CBC
        }
      );
      return decrypted.toString(CryptoJS.enc.Utf8);
    },

    loadBook(url) {
      //native.showToast("loadBook！" + url); // 调试的
      this.book = ePub(url, { requestMethod: this.myEpubRequest });
      this.rendition = this.book.renderTo("area", {
        manager: "continuous",
        width: parseInt(this.windowWidth) + "px",
        height: parseInt(this.windowHeight) + "px",
        flow: "paginated",
        snap: true
        // spreads: false,
        // forceEvenPages: true
      });

      //獲取目錄
      this.book.loaded.navigation.then(navigation => {
        //构建目录
        this.toc = navigation.toc;
        this.checkToc();
      });
      //设置hook
      this.setHook();

      this.rendition.on("relocated", locationCfi => {
        // console.log("locationCfi", JSON.stringify(locationCfi));

        //构造进度
        let index = locationCfi.start.index;
        let chapterNum = this.getChapterNum(locationCfi.start.href);

        let contents = this.rendition.getContents();

        let page = locationCfi.start.displayed.page;
        //校正页数
        if (this.checkPage && this.historyPage != page) {
          if (this.tryTime < 5) {
            this.tryTime++;
            if (this.historyPage > page) {
              //往后移动一页
              this.rendition.next();
            } else {
              //往前移动一页
              this.rendition.prev();
            }
            return;
          } else {
            this.checkPage = false;
            setTimeout(() => {
              this.showLoadingMask = false;
            }, 500);
          }
        }
        if (this.historyPage == page) {
          setTimeout(() => {
            this.showLoadingMask = false;
          }, 500);
          this.checkPage = false;
        }

        let total = locationCfi.start.displayed.total;
        this.progress = (page / total) * 100;
        let startCfi = locationCfi.start.cfi;
        let endCfi = locationCfi.end.cfi;
        let srartCfiStr = startCfi.substring(8, startCfi.length - 1);
        let endCfiStr = endCfi.substring(8, endCfi.length - 1);

        let newCfi = `epubcfi(${srartCfiStr},${endCfiStr})`;

        let cfi = locationCfi.end.cfi; // 改为了end
        let progressStr = `第${chapterNum}章第${page}頁`;

        this.progressObj = {
          href: locationCfi.start.href,
          chapter: chapterNum,
          page: page,
          cfi: startCfi
        };

        //检查当前页是否有添加书签
        let markId = this.checkBookmark(startCfi, page);

        if (markId != null) {
          this.thisPageIsMark = markId;
          if (this.isNative && this.isLogin) {
            native.showBookmarksIcon(true);
          }
        } else {
          this.thisPageIsMark = null;
          if (this.isNative && this.isLogin) {
            native.showBookmarksIcon(false);
          }
        }
        this.reportProgress(startCfi, progressStr, page);
      });

      this.registThemes(); // 注册设置皮肤
      this.setupStyle(); //设置样式

      this.rendition.on("displayed", () => {
        if (this.isNative) {
          native.hideLoading();
          setTimeout(() => {
            this.showLoadingMask = false;
          }, 500);
        }
      });

      this.rendition.on("displayError", err => {
        alert("资源解析错误", JSON.stringify(err));
      });

      // this.rendition.on("selected", (cfirange, contents) => {
      //   console.log("contents", contents);
      //   //alert("selected" + cfirange);
      // });

      if (this.historyCfi) {
        //如果有播放進度，則從上次閱讀開始
        //console.log("显示历史进度", this.historyCfi);
        this.checkPage = true;
        this.showLoadingMask = true;
        this.rendition.display(this.historyCfi);
      } else {
        //console.log("重头开始阅读");
        this.rendition.display();
      }
    },

    //上報進度
    reportProgress(cfi, progressStr, page) {
      let postD = {
        operate: "play",
        objType: "media",
        objId: this.bookId,
        extraData: JSON.stringify({
          cfi: cfi,
          progress: progressStr,
          page: page
        })
      };
      let url = this.CONFIG.OPERATE.ADD;
      this.GLOBAL_.ccRequest
        .doSessionAxios(url, postD, "POST", "no login")
        .then(res => {})
        .catch(err => {
          // console.log("上报阅读进度失败");
        });
    },

    setHook() {
      this.rendition.hooks.content.register(contents => {
        var loaded = Promise.all([
          contents.addStylesheet(this.localPathname + "static2/reader.css")
        ]);
        return loaded;
      });

      this.rendition.hooks.content.register(contents => {
        //替换图片URL
        let imgs = contents.content.querySelectorAll("img");
        imgs.forEach(img => {
          let imgSrc = img.src;

          let path = this.getPathFromUrl(imgSrc);
          let newSrc = this.getImageUrl(path);
          img.src = newSrc;
          //添加點擊事件
          img.addEventListener("click", e => {
            this.doClick(e);
          });
        });

        // //添加点击事件
        contents.document.addEventListener("click", e => {
          this.doClick(e);
        });

        //给所有的P加上事件
        let ps = contents.content.querySelectorAll("p");
        ps.forEach(p => {
          p.addEventListener("click", e => {
            this.doClick(e);
          });
        });

        //禁止a標籤跳轉
        let as = contents.content.querySelectorAll("a");
        as.forEach(a => {
          let parent = a.parentNode;
          let p = document.createElement("p");
          p.innerHTML = a.innerHTML;
          parent.replaceChild(p, a);
        });

        return contents;
      });
    },

    setupStyle() {
      //读取本地缓存，是否有已选的样式参数
      this.getSetting();
      this.rendition.themes.select(this.$config.themes[this.themeName].name);
      //设置字体,默认14
      this.rendition.themes.fontSize(
        this.$config.fontsizes[this.fontSize].size + "px"
      );
      //this.backgroundColor = this.$config.themes[this.themeName].color;
    },

    //注册皮肤
    registThemes() {
      //黑色皮肤
      this.rendition.themes.register("dark", {
        body: {
          color: "#b5b5b5 !important",
          background: "#232733 "
        },
        p: {
          color: "#b5b5b5 !important"
        },
        h1: {
          color: "#b5b5b5 !important"
        },
        h2: {
          color: "#b5b5b5 !important"
        },
        h3: {
          color: "#b5b5b5 !important"
        },
        h4: {
          color: "#b5b5b5 !important"
        },
        a: {
          color: "#b5b5b5",
          "text-decoration": " none"
        },
        img: {
          "max-width": "100%"
        }
      });
      //白色
      this.rendition.themes.register("light", {
        body: { color: "#000 !important", background: "#fff" },
        p: { color: "#000 !important" },
        h1: {
          color: "#000 !important"
        },
        h2: {
          color: "#000 !important"
        },
        h3: {
          color: "#000 !important"
        },
        h4: {
          color: "#000 !important"
        },
        a: {
          color: "#000",
          "text-decoration": " none"
        },
        img: {
          "max-width": "100%"
        }
      });
      //黄色
      this.rendition.themes.register("yellow", {
        body: {
          color: "#000 !important",
          background: "#f6f3e0"
        },
        p: { color: "#000 !important" },
        h1: {
          color: "#000 !important"
        },
        h2: {
          color: "#000 !important"
        },
        h3: {
          color: "#000 !important"
        },
        h4: {
          color: "#000 !important"
        },
        a: {
          color: "#000",
          "text-decoration": " none"
        },
        img: {
          "max-width": "100%"
        }
      });
      //绿色
      this.rendition.themes.register("green", {
        body: { color: "#000 !important", background: "#cdf0d0" },
        p: { color: "#000 !important" },
        h1: {
          color: "#000 !important"
        },
        h2: {
          color: "#000 !important"
        },
        h3: {
          color: "#000 !important"
        },
        h4: {
          color: "#000 !important"
        },
        a: {
          color: "#000",
          "text-decoration": " none"
        },
        img: {
          "max-width": "100%"
        }
      });
    },

    //打开目录
    openCatalog() {
      this.$refs.toolBar.doHide();
      this.showCatagory = new Date().getTime();
    },

    //切换上一页
    prev() {
      if (this.rendition) {
        this.rendition.prev();
      }
    },
    //切换下一页
    next() {
      // console.log("需要购买", this.needBuy);

      if (!this.needBuy && this.rendition) {
        //防止点取消购买，还可以切换下一页
        this.rendition.next();
      }
    },
    //屏幕点击事件
    doClick(e) {
      e.stopPropagation();
      e.preventDefault();
      this.clickText = e.target.innerText;

      //点击的X坐标
      // let clickX = e.clientX;
      // if (clickX < this.clientWidth / 4) {
      //   //点击屏幕左边1/4
      //   this.prev();
      // } else if (clickX > (this.clientWidth * 3) / 4) {
      //   //点击右边1/4
      //   this.next();
      // } else {
      //   this.showToolBar = new Date().getTime();
      // }
      this.showToolBar = new Date().getTime();
    },

    onChangeFontsize(fontsize) {
      this.fontSize = fontsize;
      this.rendition.themes.fontSize(
        this.$config.fontsizes[this.fontSize].size + "px"
      );
      this.saveSettingToLocal();
    },
    onThemeSelect(theme) {
      let themeConfig = this.$config.themes[theme];
      this.themeName = theme;
      this.rendition.themes.select(themeConfig.name);
      this.saveSettingToLocal();
    },

    saveSettingToLocal() {
      let settingObj = {
        fontSize: this.fontSize,
        themeName: this.themeName
      };
      //保存設置到本地
      if (this.isNative) {
        var setData = {
          key: "reader_setting",
          value: JSON.stringify(settingObj)
        };
        native.setStorage(JSON.stringify(setData));
      }
    },

    //從本地緩存中讀取
    getSetting() {
      try {
        var dataValue = native.getStorage("reader_setting");
        let settingObj = JSON.parse(dataValue);
        this.fontSize = settingObj.fontSize;
        this.themeName = settingObj.themeName;
      } catch (error) {}
    },

    //目录跳转
    gotoPage(href) {
      //判斷目標路徑是否超出閱讀限制
      //判斷是否超過試閱限制
      //console.log("跳转章节=》", href);
      let result = this.checkChapterCanRead(href, true);
      if (!result) {
        return;
      }
      this.rendition.display(href);
    },

    gotoCfi(obj) {
      let cfi = obj.cfi;
      let page = obj.page;

      this.checkPage = true;
      this.historyPage = page;
      this.tryTime = 0;
      this.rendition.display(cfi);
    }
  }
};
//
</script>

<style lang="less" scoped>
@import "~vux/src/styles/close.less";

.container {
  position: relative;
  width: 100vw;
  height: 100vh;
}

.guideMask {
  position: absolute;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  z-index: 999;
  background: rgba(0, 0, 0, 0.6);
}

.loading_mask {
  position: absolute;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  z-index: 999;
  background: rgba(255, 255, 255, 1);
}

.fade-enter-active,
.fade-leave-active {
  transition: opacity 1s;
}
.fade-enter, .fade-leave-to /* .fade-leave-active below version 2.1.8 */ {
  opacity: 0;
}

.guideMaskImg {
  width: 100vw;
  height: 100vh;
}
.mask {
  position: absolute;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  z-index: 99;
}

#area {
  padding-top: 3vh;
}

#prev {
  left: 40px;
}

#next {
  right: 40px;
}

.contents-1 {
}
</style>
